import 'package:bruno/bruno.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:yt_devops/components/gaps.dart';
import 'package:yt_devops/components/log_utils.dart';
import 'package:yt_devops/resources/resources.dart';
import 'package:yt_devops/resources/str_res_keys.dart';
import 'package:yt_devops/styles/styles.dart';
import 'package:yt_devops/utils/extensions.dart';
import 'model/m_stack.dart';
import 'model/tree_mode.dart';

class YtExpandableTree<T> extends StatefulWidget {
  /// 是否多选, 则只能操作一次
  final bool multiple;

  // /// 节点前添加 Checkbox 复选框
  // final bool checkable;

  // /// 是否可选中
  // final bool selectable;

  final Color backgroudColor;

  // 是否有下划线
  final bool showLine;

  /// 初始数据
  List<TreeNode<T>> _treeNodeData = [];

  /// 是否显示搜索
  bool isSearch;

  /// 初始选中的单选多选keys
  List<T> checkedValues;

  /// 初始选中的keys
  List<T> selectedValues;

  /// 多选切事件
  final Function(List<TreeNode<T>> newVal)? onValueChanged;

  final Function(int index, TreeNode<T> newVal)? onSelect;

  final Function(int index, TreeNode<T> newVal)? onCheck;

  /// 把树转为map
  Map _treeMap = {};

  final EdgeInsetsGeometry listPadding;

  YtExpandableTree(
      {super.key,
      // this.checkable = true,
      // this.selectable = false,
      this.isSearch = false,
      this.multiple = true,
      this.showLine = false,
      this.backgroudColor = Colors.white,
      List<TreeNode<T>> treeData = const [],
      this.listPadding = EdgeInsets.zero,
      this.checkedValues = const [],
      this.selectedValues = const [],
      this.onValueChanged,
      this.onCheck,
      this.onSelect}) {
    var checkedList =
        List.generate(checkedValues.length, (index) => checkedValues[index]);

    _treeNodeData = convertCheckedValue(
      treeData,
      checkedList,
    );
    treeData = convertSelectedValue(treeData, selectedValues);
    flatTree(_treeNodeData, null);
  }

  flatTree(List<TreeNode<T>> treeList, T? parent) {
    for (var i = 0; i < treeList.length; i++) {
      var treeModel = treeList[i];
      treeModel.prarentValue = parent;
      _treeMap.putIfAbsent(treeModel.value, () => treeModel);
      flatTree(treeModel.subNodes ?? [], treeModel.value);
    }
  }

  List<TreeNode<T>> convertCheckedValue(
    List<TreeNode<T>> data,
    List<T> checkedValueList,
  ) {
    for (var e in data) {
      var idx = checkedValueList.indexWhere((element) => element == e.value);

      if (idx > -1) {
        e.checked = 2;
        if (e.subNodes?.isNotEmpty == true) {
          setCheckStatus(e);
        }
        // checkedValueList.removeAt(idx);
      } else {
        e.checked = 0;
        if (e.subNodes?.isNotEmpty == true) {
          convertCheckedValue(e.subNodes!, checkedValueList);
          if (e.subNodes!.every((element) => element.checked == 2)) {
            e.checked = 2;
          }
        }
      }
    }
    return data;
  }

  List<TreeNode<T>> convertSelectedValue(
    List<TreeNode<T>> data,
    List<T> selectedValueList,
  ) {
    for (var e in data) {
      var idx = selectedValueList.indexWhere((element) => element == e.value);

      if (idx > -1 && e.selectable) {
        e.selected = true;
        selectedValueList.removeAt(idx);
      } else {
        e.selected = false;
      }
      if (e.subNodes?.isNotEmpty == true) {
        convertSelectedValue(e.subNodes!, selectedValueList);
      }
    }
    return data;
  }

  setCheckStatus(TreeNode item) {
    item.checked = 2;
    if (item.subNodes != null) {
      item.subNodes!.forEach((element) {
        setCheckStatus(element);
      });
    }
  }

  @override
  State<YtExpandableTree<T>> createState() => _YtExpandableTreeState<T>();
}

class _YtExpandableTreeState<T> extends State<YtExpandableTree<T>> {
  T? seletedVal;
  List<T> multiSelectVavls = [];

  String searchValue = '';

  List<TreeNode<T>> get filterTreeData => searchValue.isEmpty
      ? widget._treeNodeData
      : filterData(widget._treeNodeData, searchValue);

  @override
  void initState() {
    if (!widget.multiple) {
      if (widget.checkedValues.isNotEmpty) {
        seletedVal = widget.checkedValues[0];
      }
    } else {
      multiSelectVavls = widget.checkedValues;
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      if (widget.isSearch)
        BrnSearchText(
          maxHeight: 54,
          innerColor: Colour.backgroundColor,
          innerPadding: const EdgeInsets.fromLTRB(16, 8, 15, 8),
          hintStyle: TextStyles.lf16,
          textStyle: TextStyles.f16,
          borderRadius: BorderRadius.circular(6),
          hintText: ResKey.plsEnterKeyword.tr,
          onTextChange: (content) {
            searchValue = content;
            setState(() {});
          },
          onTextCommit: (content) {
            searchValue = content;
            setState(() {});
          },
          onTextClear: () {
            return false;
          },
        ),
      Gaps.hGap10,
      Expanded(
        child: Container(
            color: widget.backgroudColor,
            margin: const EdgeInsets.only(top: 10),
            padding: widget.listPadding,
            child: buildTree()),
      ),
    ]);
  }

  List<TreeNode<T>> filterData(List<TreeNode<T>> data, String searchValue) {
    List<TreeNode<T>> result = [];
    for (var item in data) {
      if (item.title.contains(searchValue)) {
        result.add(item);
      } else {
        if (item.subNodes?.isNotEmpty == true) {
          var arr = filterData(item.subNodes!, searchValue);
          if (arr.isNotEmpty == true) {
            item.subNodes = arr;
            result.add(item);
          }
        }
      }
    }
    return result;
  }

  onValueChange(List<TreeNode<T>> value) {
    widget.onValueChanged?.call(value);
  }

  Widget buildTree() {
    return ListView.builder(
      shrinkWrap: false,
      padding: EdgeInsets.symmetric(horizontal: 0.w),
      itemBuilder: (context, index) =>
          buildTreeNode(filterTreeData[index], 0, index, null),
      itemCount: filterTreeData.length,
    );
  }

  ///
  Widget buildTreeNode(TreeNode<T> node, int level, int index, T? parentValue) {
    Border? underline = widget.showLine
        ? const Border(
            bottom: BorderSide(color: Colour.dividerColor),
          )
        : null;

    Color? selectedBackgroudColor = node.selected ? Colors.white : null;

    return Container(
      color: selectedBackgroudColor,
      child: Column(
        children: [
          Container(
            decoration: BoxDecoration(border: underline),
            child: Row(
              children: <Widget>[
                Expanded(
                  child: GestureDetector(
                    onTap: () => onSelectNode(index, node),
                    child: Container(
                      padding: EdgeInsets.only(
                          left: 30.w * level, top: 12, bottom: 12),
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          GestureDetector(
                            onTap: () => onExpandNode(node),
                            child: Opacity(
                              opacity: isLeaf(node) ? 0 : 1,
                              child: Padding(
                                padding: EdgeInsets.only(right: 10.w),
                                child: node.expanded
                                    ? Image.asset(
                                        'assets/images/site_observer_down_arrow.png')
                                    : Image.asset(
                                        'assets/images/site_observer_right_arrow.png'),
                              ),
                            ),
                          ),
                          Expanded(
                            child: Container(
                              padding: EdgeInsets.only(left: 13.w),
                              child: Text(
                                node.title,
                                style: titleTextStyle(node),
                                maxLines: 2,
                                overflow: TextOverflow.ellipsis,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
                Offstage(
                    offstage: node.checkable == false,
                    child: widget.multiple
                        ? checkboxButton(
                            node,
                            level * 10 + index,
                          )
                        : radioButton(
                            node,
                            level * 10 + index,
                          )),
              ],
            ),
          ),

          /// 可展开收起项
          if (isExpand(node))
            Column(
              children: node.subNodes!
                  .mapIndexed(
                      (e, idx) => buildTreeNode(e, level + 1, idx, node.value))
                  .toList(),
            )
        ],
      ),
    );
  }

  TextStyle? titleTextStyle(TreeNode node) {
    if (node.selected) {
      return TextStyles.pf14;
    }
    return null;
  }

  Widget checkboxButton(
    TreeNode<T> node,
    int index,
  ) {
    // Log.d((node.checked == 2).toString());
    return BrnCheckbox(
      key: GlobalKey(),
      radioIndex: index,
      childOnRight: false,
      disable: node.disableCheckbox,
      isSelected: node.checked == 2,
      onValueChangedAtIndex: (position, value) {
        onSelectCheckBox(index, node);
      },
    );
  }

  /// 单选
  Widget radioButton(
    TreeNode<T> node,
    int index,
  ) {
    return BrnRadioCore(
      radioIndex: index,
      disable: node.disableCheckbox,
      isSelected: node.checked == 2,
      childOnRight: false,
      selectedImage: BrunoTools.getAssetImageWithBandColor(
          BrnAsset.iconRadioSingleSelected),
      unselectedImage: BrunoTools.getAssetImage(BrnAsset.iconRadioUnSelected),
      disSelectedImage:
          BrunoTools.getAssetImage(BrnAsset.iconRadioDisableMultiSelected),
      disUnselectedImage:
          BrunoTools.getAssetImage(BrnAsset.iconRadioDisableUnselected),
      onRadioItemClick: () {
        onSingleSelect(
          index,
          node,
          node.checked == 2 ? false : true,
        );
      },
    );
  }

  onSingleSelect(int index, TreeNode<T> node, bool select) {
    if (select) {
      /// 选中节点：
      /// 1.清除兄弟节点状态
      /// 2.更新到上下级所有节点
      List<TreeNode<T>> sblings = [];
      TreeNode<T>? par = widget._treeMap[node.prarentValue];
      if (par == null) {
        sblings = filterTreeData;
      } else {
        sblings = par.subNodes ?? [];
      }
      widget.convertCheckedValue(sblings, []);
      onSelectCheckBox(index, node);
    } else {
      /// 取消节点：
      /// 更新本节点以及上下级节点
      onSelectCheckBox(index, node);
    }
  }

  onSelectCheckBox(int index, TreeNode<T> node) {
    ///子节点
    updateChildrenNode(node);

    // 父节点
    if (node.prarentValue != null) {
      updateParentNode(node);
    }
    setState(() {
      widget._treeNodeData = widget._treeNodeData;
    });
    var checkedLIst = getCheckedItems();
    if (checkedLIst.indexWhere((item) => item.value == node.value) > -1) {
      widget.onCheck?.call(index, node);
    }
  }

  /// 获取选中的节点
  List<TreeNode<T>> getCheckedItems() {
    var stack = MStack();
    List<TreeNode<T>> checkedList = [];
    for (var item in widget._treeNodeData) {
      stack.push(item);
    }
    while (stack.top > 0) {
      TreeNode<T> node = stack.pop();
      for (var item in (node.subNodes ?? [])) {
        stack.push(item);
      }
      if (node.checked == 2 && node.checkable) {
        checkedList.add(node);
      }
    }

    // logger.v(checkedList.length);

    // List中多余的元素
    var list1 = [];
    for (var value2 in checkedList) {
      if (value2.subNodes != null && value2.subNodes!.isNotEmpty) {
        for (var value in checkedList) {
          if (value2.value == value.prarentValue) {
            list1.add(value);
          }
        }
      }
    }

    // 移除List中多余的元素
    var set = Set.from(checkedList);
    var set2 = Set.from(list1);
    List<TreeNode<T>> filterList = List.from(set.difference(set2));
    widget.onValueChanged?.call(filterList);
    return filterList;

    // Log.d('选中数量  ${filterList.length.toString()}');
  }

  updateParentNode(TreeNode<T> dataModel) {
    TreeNode<T>? par = widget._treeMap[dataModel.prarentValue];
    if (par == null) return;
    int checkLen = 0;
    bool partChecked = false;
    for (TreeNode<T> item in (par.subNodes ?? [])) {
      if (item.checked == 2) {
        checkLen++;
      } else if (item.checked == 1) {
        partChecked = true;
        break;
      }
    }

    // 如果子孩子全都是选择的， 父节点就全选
    if (checkLen == (par.subNodes ?? []).length) {
      par.checked = 2;
    } else if (partChecked ||
        (checkLen < (par.subNodes ?? []).length && checkLen > 0)) {
      par.checked = 1;
    } else {
      par.checked = 0;
    }

    // 如果还有父节点 解析往上更新
    if (par.prarentValue != null && widget._treeMap[par.prarentValue] != null) {
      updateParentNode(par);
    }
  }

  updateChildrenNode(TreeNode<T> node) {
    if ((node.subNodes ?? []).isNotEmpty) {
      var stack = MStack();
      stack.push(node);
      while (stack.top > 0) {
        TreeNode child = stack.pop();
        for (var item in child.subNodes ?? []) {
          stack.push(item);
        }
        if (child.checked == 2) {
          child.checked = 0;
        } else {
          child.checked = 2;
        }
      }
    } else {
      if (node.checked == 2) {
        node.checked = 0;
      } else {
        node.checked = 2;
      }
    }
  }

  updateSblingParentNode(TreeNode<T> dataModel) {
    TreeNode<T>? par = widget._treeMap[dataModel.prarentValue];
    List<TreeNode<T>> subNodes = [];
    if (par == null) {
      subNodes = filterTreeData;
    } else {
      subNodes = par.subNodes ?? [];
    }

    for (TreeNode<T> item in subNodes) {
      if (item.value == dataModel.value) {
        item.checked = 0;
      } else {
        item.checked = 2;
      }
      updateChildrenNode(item);
    }
  }

  // 触发选中
  void onSelectNode(int index, TreeNode<T> node) {
    if (node.selectable && widget.onSelect != null) {
      widget.onSelect!(index, node);
    }
  }

  /// 触发展开收缩
  void onExpandNode(TreeNode node) {
    //  if (!node.isLeaf)
    node.expanded = !node.expanded;
    setState(() {});
  }

  ///
  bool isExpand(TreeNode node) {
    return node.expanded && node.subNodes?.isNotEmpty == true;
  }

  ///
  bool isLeaf(TreeNode node) {
    return node.isLeaf || node.subNodes == null || node.subNodes!.isEmpty;
  }
}
